#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "board.h"
#include "base_card.h"

#ifdef TEXT_MODE
#include "card_img.h"
static char board_pixels[BOARD_PIXEL_SIZE];
#endif

static int board[BOARD_SIZE];
static int top_most = BOARD_HEIGHT - 1;
static int right_most = 0;
static int bottom_most = 0;
static int left_most = BOARD_WIDTH -1;

void auto_rotate(int idx, int flag, int dir)
{
	// map dir:   0 1 2 3
	//  to value: 8 4 2 1
	//  8 >> 0
	//  8 >> 1
	//  8 >> 2
	//  8 >> 3
	int weight = 8 >> dir;
#if 0
	switch(dir)
	{
		case TOP:
			weight = 8;
			break;
		case RIGHT:
			weight = 4;
			break;
		case BOTTOM:
			weight = 2;
			break;
		default:
		case LEFT:
			weight = 1;
	}
#endif
	if(flag & (0x0001*weight))
		return;
	else if(flag & (0x0010*weight))
	{	
		printf("Card %02d Right rotate 90!\n", idx);
		card_rotate(idx, ROTATE_RIGHT_90);
		return;
	}
	else if(flag & (0x0100*weight))
	{
		printf("Card %02d Right rotate 180!\n", idx);
		card_rotate(idx, ROTATE_RIGHT_180);
		return;
	}
	else if(flag & (0x1000*weight))
	{
		printf("Card %02d Right rotate 270!\n", idx);
		card_rotate(idx, ROTATE_RIGHT_270);
		return;
	}
}
// Only be called when set_board_card() called.
static void set_board_boudary(int x, int y)
{
	if(x >= 0)
	{
		if(x < left_most)
			left_most = x;
		if(x > right_most)
			right_most = x;
	}
	if(y >= 0)
	{
		if(y < top_most)
			top_most = y;
		if(y > bottom_most)
			bottom_most = y;
	}
}
int board_occupy(int x, int y)
{
	if(x < 0 || y < 0 || x > BOARD_WIDTH || y > BOARD_HEIGHT)
		return BOARD_OUTOF_RANGE;
	return board[y*BOARD_WIDTH + x];
}
int get_board_top()
{
	return top_most;
}
int get_board_right()
{
	return right_most;
}
int get_board_bottom()
{
	return bottom_most;
}
int get_board_left()
{
	return left_most;
}
int *get_board()
{
	return board;
}
void init_board()
{
	memset(board, BOARD_NOT_OCCUPY, sizeof(int)*BOARD_SIZE);
#ifdef TEXT_MODE
	memset(board_pixels, ' ', sizeof(char)*BOARD_PIXEL_SIZE);
#endif
}
void print_board()
{
	int i, j;
	/*
	for(i=0; i<BOARD_HEIGHT; i++)
	{
		for(j=0;j<BOARD_WIDTH; j++)
			printf("%3d ", board[i*BOARD_WIDTH + j]);
		printf("\n");
	}
	*/
	for(i=top_most; i<bottom_most+1; i++)
	{
		for(j=left_most;j<right_most+1; j++)
			printf("%3d ", board[i*BOARD_WIDTH + j]);
		printf("\n");
	}
}
#ifdef TEXT_MODE
char *get_board_pixels()
{
	return board_pixels;
}
void print_board_pixels()
{
	int i, j;
	for(i=top_most*CARD_HEIGHT; i<(bottom_most+1)*CARD_HEIGHT; i++)
	{
		for(j=left_most*CARD_WIDTH;j<(right_most+1)*CARD_WIDTH; j++)
			printf("%c", board_pixels[i*BOARD_PIXEL_W + j]);
		printf("\n");
	}
}
static char set_1_pic_pixels(struct card *this,const int i,const int j,enum CARD_ORIENTATION orien)
{
	char *card_img = get_card_image(this->card_type);
	if(orien == ORIEN_N) return card_img[i*CARD_WIDTH+j];
	else if(orien == ORIEN_E) return card_img[(CARD_HEIGHT-j-1)*CARD_WIDTH+i];
	else if(orien == ORIEN_S) return card_img[(CARD_HEIGHT-i-1)*CARD_WIDTH+(CARD_WIDTH-j-1)];
	else return card_img[(CARD_HEIGHT-(CARD_HEIGHT-j-1)-1)*CARD_WIDTH+(CARD_WIDTH-i-1)];
} 
static void set_full_pic_pixels(struct card *this,char *board_pixels,int location)
{
	int i,j;
	for(i=0;i<CARD_HEIGHT;i++)
	{
		for(j=0;j<CARD_WIDTH;j++)
		{
			board_pixels[location+j] = set_1_pic_pixels(this,i,j,this->card_orien);
		}
		location += BOARD_PIXEL_W;
	}
}



static void print_card_1_pixels(const int i,const int j,const struct card *this,const char *card_img)
{
//	char *card_img = get_card_image(this->card_type);
	if(this->card_orien == ORIEN_N) printf("%c",card_img[i*CARD_WIDTH+j]);
	else if(this->card_orien == ORIEN_E) printf("%c", card_img[(CARD_HEIGHT-j-1)*CARD_WIDTH+i]);
	else if(this->card_orien == ORIEN_S) printf("%c", card_img[(CARD_HEIGHT-i-1)*CARD_WIDTH+(CARD_WIDTH-j-1)]);
	else printf("%c", card_img[(CARD_HEIGHT-(CARD_HEIGHT-j-1)-1)*CARD_WIDTH+(CARD_WIDTH-i-1)]);
}




void print_card_pixels(int idx)
{
	struct card *this;
	this = get_card(idx);
	assert(this!=NULL);
	char *card_img;
	card_img = get_card_image(this->card_type);
	int i, j;
					
	for(i=0;i<CARD_HEIGHT;i++)
	{
		for(j=0;j<CARD_WIDTH;j++)
		{
			print_card_1_pixels(i,j,this,card_img);
		}
		printf("\n");
	}
}
#endif


// print card to board_pixels
void set_board_card(int idx, int board_x, int board_y)
{
	struct card *this;
	this = get_card(idx);
	assert(this!=NULL);

	set_card_pos(idx, board_x, board_y);
	set_board_boudary(board_x, board_y);
	printf("set card: %d to board(%d,%d)\n", idx, board_x, board_y);	
	board[board_y*BOARD_WIDTH + board_x] = idx;
#ifdef TEXT_MODE
	int location = board_y * CARD_HEIGHT * BOARD_PIXEL_W + board_x * CARD_WIDTH;
	set_full_pic_pixels(this,board_pixels,location);
#endif
}
void show_card_image(int idx)
{
#ifdef TEXT_MODE
	print_card_pixels(idx);
#endif
}
void show_board()
{
#ifdef TEXT_MODE
	print_board_pixels();
#endif
}
